package demo06.third;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: WangPeng
 * @createTime: 2022/11/06 16:28
 * @description:
 * @version: v1.0
 */
public class Test01 {
    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("欧阳雪",18,"中国",'F'));
        personList.add(new Person("Tom",24,"美国",'M'));
        personList.add(new Person("Harley",22,"英国",'F'));
        personList.add(new Person("向天笑",20,"中国",'M'));
        personList.add(new Person("李康",22,"中国",'M'));
        personList.add(new Person("小梅",20,"中国",'F'));
        personList.add(new Person("何雪",21,"中国",'F'));
        personList.add(new Person("李康1",22,"中国",'M'));

        Integer[] arr1 = {1,2,3,4,5};
        Integer[] arr2 = {1,3,5,6,7};
        //获取stream流
        Stream<Integer> stream1 = Stream.of(arr1);
        Stream<Integer> stream2 = Stream.of(arr2);

    //1、filter--该方法需要一个断言型函数式接口参数，满足条件的留下，不满足条件的过滤掉。
        //使用filter筛选出中国人
        personList.stream().filter(item->item.getCountry().equals("中国")).forEach(System.out::println);
    //2、map--接收Lambda，将元素转换成其他形式或提取信息。接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
        //使用mapmap映射操作获取集合中所有对象的国籍
        personList.stream().map(item->item.getCountry()).forEach(System.out::println);
    //3、sort排序操作
        //按年龄排序
        personList.stream().sorted((o1,o2)->o1.getAge()-o2.getAge()).forEach(System.out::println);
    //4、concat:提取和组合----提取和组合
        //4.1、合并流
        Stream.concat(stream1,stream2).forEach(System.out::println);
        //4.2、去重---distinct()
        Stream.concat(stream1,stream2).distinct().forEach(System.out::println);
        //4.3、获取前n个元素--limit(n)--合并之后的前n个元素
        Stream.concat(stream1,stream2).limit(7).forEach(System.out::println);
        //4.4、跳过前n个元素--skip(n)----合并之后的跳过前n个元素
        Stream.concat(stream1,stream2).skip(6).forEach(System.out::println);
    //5、find操作--findFirst和findAny
        //5.1、findFirst获取流中第一个元素
        Optional<Person> first = personList.stream().findFirst();
        System.out.println(first.get());
        //5.2、findAny()获取流中任意一个元素  必须使用并行流parallelStream()测试
        Optional<Person> any = personList.parallelStream().findAny();
        System.out.println(any.get());
    //6、match 匹配操作--allMatch anyMatch
        //6.1、allMatch匹配操作--所有元素都必须匹配条件 才返回true
        boolean b1 = personList.stream().allMatch(item -> item.getAge() > 10);
        System.out.println("b1 = " + b1);
        //6.2、anyMatch匹配操作--任意元素匹配条件 返回true
        boolean b2 = personList.stream().anyMatch(item -> item.getAge() > 20);
        System.out.println("b2 = " + b2);
    //7、聚合操作
        //7.1、count统计个数
        long count = personList.stream().filter(item -> item.getAge() > 20).count();
        System.out.println("count = " + count);
        //7.2、max--最大值
        Optional<Person> max = personList.stream().max((o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println(max.get());
        //7.3、min--最小值
        Optional<Person> min = personList.stream().min((o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println(min.get());
    //8、reduce规约操作--把一个流浓缩成一个值，能实现对集合的求和、求乘积、求最值
        //第一次赋值时，会把集合中的前两个元素赋值于t1 t2   后面会把方法计算的结果赋予t1  在集合的后面的元素赋予t2
        //求和
        Optional<Integer> reduce1 = stream1.reduce((o1, o2) -> o1 += o2);
        System.out.println(reduce1.get());
        //求乘积
        Optional<Integer> reduce2 = stream2.reduce((t1, t2) -> t1 *= t2);
        System.out.println(reduce2.get());
        //求最值
        Optional<Integer> reduce3 = stream1.reduce((t1, t2) -> t1>t2?t1:t2);
        System.out.println(reduce3.get());
    //9、collect搜集
        //9.1、计数： count
        Long collect = personList.stream().collect(Collectors.counting());
        System.out.println("collect = " + collect);
        //9.2、获取年龄的平均值： averagingInt、 averagingLong、 averagingDouble
        Double collect1 = personList.stream().collect(Collectors.averagingInt(item -> item.getAge()));
        System.out.println("collect1 = " + collect1);
        //9.3、获取年龄的最值： maxBy、 minBy
        Optional<Person> collect2 = personList.stream().collect(Collectors.maxBy((o1, o2) -> o1.getAge() - o2.getAge()));
        System.out.println(collect2.get());
        //9.4、获取年龄的和： summingInt、 summingLong、 summingDouble
        Integer collect3 = personList.stream().collect(Collectors.summingInt(item -> item.getAge()));
        System.out.println("collect3 = " + collect3);
        //在collect搜集的基础上把筛选的元素放到一个新的List、Map、Set中
        //9.5、存放到新的List集合中
        List<Person> list = personList.stream().filter(item -> item.getAge() >= 20).collect(Collectors.toList());
        System.out.println("list = " + list);
        //9.6、存放到新的Map集合中
        Map<String, Person> map = personList.stream().collect(Collectors.toMap(item -> item.getName(), item -> item));
        System.out.println("map = " + map);
        //9.7、存放到新的Set集合中
        Set<Person> set = personList.stream().filter(item->item.getCountry().equals("中国")).collect(Collectors.toSet());
        System.out.println("set = " + set);
    //10、分组
        //按照性别分组--返回结果为Map--以分组的条件作为key,已满足分组条件的元素作为value
        Map<String, List<Person>> listMap = personList.stream().collect(Collectors.groupingBy(item -> item.getCountry()));
        System.out.println("listMap = " + listMap);
    }
}
class Person {
    private String name;
    private Integer age;
    private String country;
    private char sex;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", country='" + country + '\'' +
                ", sex=" + sex +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public Person(String name, Integer age, String country, char sex) {
        this.name = name;
        this.age = age;
        this.country = country;
        this.sex = sex;
    }
}


